#include <windows.h>
#include <stdio.h>
#include "Param.h"

TParam paramList[] = 
{
	param_normal("x", "width", "map width", ptype_int),
	param_normal("y", "height", "map height", ptype_int),
	param_normal("lay", "layers", "layer count", ptype_int),

	param_simple("input_file", "The input file", true),
	param_simple("output_file", "The output file", true)
};

enum
{
	PARAM_X = 0,
	PARAM_Y,
	PARAM_LAY,
	PARAM_INPUT,
	PARAM_OUTPUT
}EParams;

char *alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int getLetter(char c)
{
	for (int i=0;i<64;i++)
	{
		if (alphabet[i] == c)
			return i;
	}
	return -1;
}

void decodeBase64(char *in, unsigned char *out, int len)
{
	long v = 0;
	int p=0;

	for (int i=0;i<len*4;i++)
	{
		if (i%3==0)
		{
			v = (getLetter(in[p]) << 18) | (getLetter(in[p+1]) << 12) | (getLetter(in[p+2]) << 6) | (getLetter(in[p+3]));
			p+=4;
		}
		
		if (i%4==0)
			out[i/4] = (v & 0x00ff0000) >> 16;
		v <<= 8;
	}
}

int main(int argc, char **argv)
{
	//parse command line
	if (!parseCommand(argc, argv, paramList, sizeof(paramList) / sizeof(TParam),"(c)2008 Claudiu-Florin FILIMON"))
		return -1;


	FILE *fin,*fout;

	fin = fopen(paramList[PARAM_INPUT].strValue, "rt");
	if (!fin)
	{
		printf("Could not open file %s\n", paramList[PARAM_INPUT].strValue);
		return -1;
	}

	fout = fopen(paramList[PARAM_OUTPUT].strValue, "wb");
	if (!fout)
	{
		printf("Could not open file %s\n", paramList[PARAM_OUTPUT].strValue);
		return -1;
	}

	fwrite("MP",2,1,fout);
	short v = 0;
	fwrite(&v,2,1,fout);//flags
	v=paramList[PARAM_X].intValue;
	fwrite(&v,2,1,fout);//x
	v=paramList[PARAM_Y].intValue;
	fwrite(&v,2,1,fout);//y
	v=paramList[PARAM_LAY].intValue;
	fwrite(&v,2,1,fout);//layers

	char line[65536];
	int sz = paramList[PARAM_X].intValue * paramList[PARAM_Y].intValue;
	unsigned char *data = new unsigned char[sz];
	for (int i=0;i<paramList[PARAM_LAY].intValue;i++)
	{
		fgets(line, 65536, fin);
		decodeBase64(line, data, sz);
		fwrite(data, sz, 1, fout);
	}

	fclose(fin);
	fclose(fout);

	return 0;
}